<?php

class ClienteService extends Model {

    /**
     * @var ClienteDao
     */
    private $clienteDao;
    /**
     * @var AtendimentoService
     */
    private $atendimentoService;
    /**
     * @var ComunicadoService
     */
    private $comunicadoService;
    /**
     * @var LancamentoService
     */
    private $lancamentoService;
    /**
     * @var FinanceiroService
     */
    private $financeiroService;
    /**
     * @var AvaliacaoService
     */
    private $avaliacaoService;

    public function injectDependencies() {
        $this->clienteDao = ClienteDao::getInstance();
        $this->atendimentoService = AtendimentoService::getInstance();
        $this->comunicadoService = ComunicadoService::getInstance();
        $this->historicoSituacaoService = HistoricoSituacaoService::getInstance();
        $this->lancamentoService = LancamentoService::getInstance();
        $this->financeiroService = FinanceiroService::getInstance();
        $this->avaliacaoService = AvaliacaoService::getInstance();
    }

    public function findAll($AsSimple = false) {
        $ArCustomers = $this->clienteDao->findAll();
        if( !$AsSimple ) {
            $this->fillCustomer($ArCustomers);
        }
        return $ArCustomers;
    }

    public function findWithBilletPayment() {
        $ArCustomers = $this->clienteDao->findWithBilletPayment();
        $this->fillCustomer($ArCustomers);
        return $ArCustomers;
    }

    public function findById($IDCliente) {
        $Customer =  $this->clienteDao->findById($IDCliente);
        $this->fillCustomer($Customer);
        return $Customer;
    }

    public function findByFinancial($IDFinanceiro) {
        $Customer = $this->clienteDao->findByFinancial($IDFinanceiro);
        $this->fillCustomer($Customer);
        return $Customer;
    }

    public function findByPayment($IDCobranca) {
        $Customer = $this->clienteDao->findByPayment($IDCobranca);
        $this->fillCustomer($Customer);
        return $Customer;
    }

    //07-04
    public function save($ArDados) {
        return $this->clienteDao->save($ArDados);
    }
    //junho
    public function getListOfIdexedCity() {
        return $this->clienteDao->getListOfCustomerCities();
    }

    public function generateSearchParameters($ArSearchParameters) {
        $ArDados = array();
        foreach($ArSearchParameters as $StKey => $MxParameters) {
            if( !empty($MxParameters) ) {
                $ArDados[$StKey] = $MxParameters;
            }
        }
        return $ArDados;
    }

    public function searchCustomerByFilter($ArDados) {
        return $this->isAdvancedSearch($ArDados) ? $this->doAdvancedSearch($ArDados) : $this->doSimpleSearch($ArDados);;
    }

    private function isAdvancedSearch($ArDados) {
        return !isset($ArDados['IDCliente']) && !isset($ArDados['StCpf']) && !isset($ArDados['StCnpj']);
    }

    private function doAdvancedSearch($ArDados) {
        return $this->clienteDao->advancedSearch($ArDados);
    }

    private function doSimpleSearch($ArDados) {
        if( !empty($ArDados['IDCliente']) ) {
            $Customer = $this->clienteDao->findById($ArDados['IDCliente']);
            return !empty($Customer) ? array($this->clienteDao->findById($ArDados['IDCliente'])) : false;
        }
        return $this->clienteDao->findByDocument($ArDados);
    }

    public function fillCustomer(&$MxCustomer) {
        if( !empty($MxCustomer) ) {
            $this->fillCustomerWithHisCalleds($MxCustomer);
            $this->fillCustomerWithHisCommunications($MxCustomer);
            $this->fillCustomerWithSituationHistory($MxCustomer);
            $this->fillCustomerWithHisReleases($MxCustomer);
        }
    }

    private function fillCustomerWithHisCalleds(&$MxCustomer) {
        if( !is_array($MxCustomer) ) {
            $MxCustomer->setArChamados( $this->atendimentoService->findCalledByCustomer($MxCustomer->getIDCliente()) );
            return;
        }
        foreach($MxCustomer as &$Customer) {
            $Customer->setArChamados( $this->atendimentoService->findCalledByCustomer($Customer->getIDCliente()) );
        }
    }

    private function fillCustomerWithHisCommunications(&$MxCustomer) {
        if( !is_array($MxCustomer) ) {
            $MxCustomer->setArComunicados( $this->comunicadoService->findCommunicationsByCustomer($MxCustomer->getIDCliente()) );
            return;
        }
        foreach($MxCustomer as &$Customer) {
            $Customer->setArComunicados( $this->comunicadoService->findCommunicationsByCustomer($Customer->getIDCliente()) );
        }
    }

    private function fillCustomerWithSituationHistory(&$MxCustomer) {
        if( !is_array($MxCustomer) ) {
            $MxCustomer->setArHistoricoSituacao( $this->historicoSituacaoService->findByCustomer( $MxCustomer->getIDCliente() ) );
            return;
        }
        foreach($MxCustomer as &$Customer) {
            $Customer->setArHistoricoSituacao( $this->historicoSituacaoService->findByCustomer( $Customer->getIDCliente() ) );
        }
    }

    private function fillCustomerWithHisReleases(&$MxCustomer) {
        if( !is_array($MxCustomer) ) {
            $MxCustomer->setArLancamentos( $this->lancamentoService->findByCustomer( $MxCustomer->getIDCliente() ) );
            return;
        }
        foreach($MxCustomer as &$Customer) {
            $Customer->setArLancamentos( $this->lancamentoService->findByCustomer( $Customer->getIDCliente() ) );
        }
    }

    /* Vinicius */
    public function countNumberOfCustomerRegisterByLoggedUser($ArPeriod = false) {
        return $this->clienteDao->numberOfCustomerRegisterByLoggedUser($ArPeriod);
    }

    public function countNumberOfCustomerRegisterByUser($IDUsuario, $ArPeriod = false) {
        return $this->clienteDao->countNumberOfCustomerRegisterByUser($IDUsuario, $ArPeriod);
    }

    public function countNumberOfCustomerRegisterBySector($IDSetor, $ArPeriod = false) {
        return $this->clienteDao->countNumberOfCustomerRegisterBySector($IDSetor, $ArPeriod);
    }

    public function countNumberOfCustomerRegisterByDepartament($IDDepartament, $ArPeriod = false) {
        return $this->clienteDao->countNumberOfCustomerRegisterByDepartament($IDDepartament, $ArPeriod);
    }

     public function update($ArDados) {
        return $this->clienteDao->update($ArDados);
    }

    public function generatePaymentFinancialReport($IDFinanceiro) {
        $Customer = $this->findByFinancial($IDFinanceiro);
        $ArReportLines = array();
        $ArReportLines[] = array(
            'MounthlyPaymentsNumber' => $this->financeiroService->countMounthlyPaymentsByFinancial($IDFinanceiro),
            'ReceivedTotalValue' => MathUtils::money($this->financeiroService->getReceivedTotalValueFromFinancial($IDFinanceiro)),
            'HomeTime' => $Customer->daysSinceRegister()
        );
        return $ArReportLines;
    }

    public function generatePaymentTypeFinancialReport($IDFinanceiro) {
        $ArReportLines = array();
        $ArReportLines[] = array(
            'BillPayment' => $this->financeiroService->countBillPaymentByFinancial($IDFinanceiro),
            'CreditCardPayment' => $this->financeiroService->countCreditCardPaymentByFinancial($IDFinanceiro),
        );
        return $ArReportLines;
    }

    public function generateHistoryFinancialReport($IDFinanceiro) {
        $ItMounthlyPayments = $this->financeiroService->countMounthlyPaymentsByFinancial($IDFinanceiro);
        $ArReportLines = array();
        $ArReportLines[] = array(
            'Frozen' => $this->financeiroService->countFrozenTimesByFinancial($IDFinanceiro),
            'PreFrozen' => $this->financeiroService->countPreFrozenTimesByFinancial($IDFinanceiro),
            'Delays' => $this->financeiroService->countDelayTimesByFinancial($IDFinanceiro),
        );
        $ArReportLines[0]['DelaysPercentage'] = MathUtils::getPercent($ItMounthlyPayments, $ArReportLines[0]['Delays']);
        return $ArReportLines;
    }

    public function findWithPendingMonthly() {
        $Customer = $this->clienteDao->findCustomerWithPendingMonthly();
        $this->fillCustomer($Customer);
        return $Customer;
    }

    public function findCustomersWithId($ArCustomersIds) {
        if( empty($ArCustomersIds) ) { return array(); }
        $ArCustomers =  $this->clienteDao->findCustomersInId($ArCustomersIds);
        $this->fillCustomer($ArCustomers);
        return $ArCustomers;
    }

    public function findOldersActiveCustomerInSystem($ItLimit) {
        $ArCustomers = $this->clienteDao->findOldersActiveCustomerInSystem($ItLimit);
        $this->fillCustomer($ArCustomers);
        return $ArCustomers;
    }

    public function generateTreatmentReport() {
        return array(
            'CHAMADOS_CRIADOS' => $this->clienteDao->findCustomerWithMoreCalledByType('EXTERNO', array('ATENDENTE', 'CLIENTE')),
            'CHAMADOS_FECHADOS' => $this->clienteDao->findCustomerWithMoreCalledByType('EXTERNO', array('FECHADO')),
            'CHAMADOS_TELEFONICOS' => $this->clienteDao->findCustomerWithMoreCalledByType('TELEFONICO', array('TELEFONICO')),
            'CHAMADOS_PERFEITOS' => $this->clienteDao->findCustomerWithMorePerfectCalleds()
        );
    }

    public function generateSatisfactionReport() {
        return $this->avaliacaoService->generateSatisfactionReport();
    }

    public function generateSatisfactionEvaluationsReport() {
        return array(
            'OTIMO' => $this->avaliacaoService->countNumberOfEvaluationsType('OTIMO'),
            'MUITO BOM' => $this->avaliacaoService->countNumberOfEvaluationsType('MUITO BOM'),
            'REGULAR' => $this->avaliacaoService->countNumberOfEvaluationsType('REGULAR'),
            'PESSIMO' => $this->avaliacaoService->countNumberOfEvaluationsType('PESSIMO')
        );
    }

    public function generateEvaluationsNumberReport() {
        return $this->avaliacaoDao->generateEvaluationsNumberReport();
    }

    public function findBySituation($EnSituacao) {
        $ArCustomers = $this->clienteDao->findCustomerBySituation($EnSituacao);
        $this->fillCustomer($ArCustomers);
        return $ArCustomers;
    }

    public function findSimpleCustomerById($IDCliente) {
        return $this->clienteDao->findSimpleCustomerById($IDCliente);
    }
}

?>
